<template>
  <div class="sudoku-container">
    <div class="game-wrapper">
      <!-- 游戏主区域 -->
      <div class="game-board">
        <div v-for="(row, i) in board" 
             :key="i" 
             class="board-row">
          <div v-for="(cell, j) in row" 
               :key="j"
               class="board-cell"
               :class="{
                 'selected': selectedCell.row === i && selectedCell.col === j,
                 'highlighted': isHighlighted(i, j),
                 'fixed': cell.fixed,
                 'error': hasError(i, j)
               }"
               @click="selectCell(i, j)">
            {{ cell.value || '' }}
          </div>
        </div>
      </div>

      <!-- 数字选择面板 -->
      <div class="number-pad">
        <button v-for="n in 9" 
                :key="n"
                class="number-button"
                :disabled="!canUseNumber(n)"
                @click="fillNumber(n)">
          {{ n }}
        </button>
        <button class="number-button clear"
                @click="clearCell">
          清除
        </button>
      </div>

      <!-- 游戏控制面板 -->
      <div class="control-panel">
        <div class="game-stats">
          <div class="stat-item">
            <span class="stat-label">难度</span>
            <span class="stat-value">{{ difficultyText }}</span>
          </div>
          <div class="stat-item">
            <span class="stat-label">用时</span>
            <span class="stat-value">{{ formatTime(gameTime) }}</span>
          </div>
          <div class="stat-item">
            <span class="stat-label">错误</span>
            <span class="stat-value" :class="{ 'danger': errors > 2 }">
              {{ errors }}/3
            </span>
          </div>
        </div>

        <div class="button-group">
          <button class="control-button primary" 
                  @click="startNewGame"
                  :disabled="isPlaying && !gameOver">
            新游戏
          </button>
          <button class="control-button" 
                  @click="togglePause"
                  :disabled="!isPlaying || gameOver">
            {{ isPaused ? '继续' : '暂停' }}
          </button>
          <button class="control-button"
                  @click="checkSolution"
                  :disabled="!isPlaying || gameOver">
            检查
          </button>
        </div>

        <div class="difficulty-select">
          <label>选择难度:</label>
          <select v-model="difficulty">
            <option value="easy">简单</option>
            <option value="medium">中等</option>
            <option value="hard">困难</option>
          </select>
        </div>

        <div class="game-instructions">
          <h3>游戏规则</h3>
          <ul>
            <li>每行、每列和每个3x3宫格内数字1-9不能重复</li>
            <li>点击格子后可以填入数字</li>
            <li>固定数字不能修改</li>
            <li>3次错误游戏结束</li>
          </ul>
        </div>
      </div>

      <!-- 游戏结束弹窗 -->
      <div v-if="gameOver" class="game-over">
        <div class="game-over-content">
          <h2>{{ isWin ? '恭喜通关!' : '游戏结束' }}</h2>
          <div class="result-stats">
            <div class="stat-row">
              <span>用时</span>
              <span>{{ formatTime(gameTime) }}</span>
            </div>
            <div class="stat-row">
              <span>难度</span>
              <span>{{ difficultyText }}</span>
            </div>
            <div class="stat-row">
              <span>错误次数</span>
              <span>{{ errors }}</span>
            </div>
          </div>
          <button class="restart-button" @click="startNewGame">
            再来一局
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'

// 游戏配置
const BOARD_SIZE = 9
const MAX_ERRORS = 3

// 游戏状态
const board = ref([])
const selectedCell = ref({ row: -1, col: -1 })
const difficulty = ref('medium')
const isPlaying = ref(false)
const isPaused = ref(false)
const gameOver = ref(false)
const isWin = ref(false)
const errors = ref(0)
const gameTime = ref(0)

let gameTimer = null

// 计算属性
const difficultyText = computed(() => {
  const texts = {
    easy: '简单',
    medium: '中等',
    hard: '困难'
  }
  return texts[difficulty.value]
})

// 初始化游戏
const initBoard = () => {
  board.value = Array(BOARD_SIZE).fill().map(() => 
    Array(BOARD_SIZE).fill().map(() => ({
      value: 0,
      fixed: false
    }))
  )
}

// 生成数独谜题
const generatePuzzle = () => {
  // 首先生成完整的解决方案
  generateSolution(0, 0)
  
  // 根据难度移除一些数字
  const cellsToRemove = {
    easy: 30,
    medium: 40,
    hard: 50
  }[difficulty.value]

  let count = cellsToRemove
  while (count > 0) {
    const row = Math.floor(Math.random() * BOARD_SIZE)
    const col = Math.floor(Math.random() * BOARD_SIZE)
    if (board.value[row][col].value !== 0) {
      board.value[row][col].value = 0
      count--
    }
  }

  // 标记固定的数字
  board.value.forEach(row => {
    row.forEach(cell => {
      cell.fixed = cell.value !== 0
    })
  })
}

// 生成解决方案
const generateSolution = (row, col) => {
  if (col >= BOARD_SIZE) {
    row++
    col = 0
  }
  if (row >= BOARD_SIZE) {
    return true
  }

  if (board.value[row][col].value !== 0) {
    return generateSolution(row, col + 1)
  }

  const numbers = shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9])
  for (const num of numbers) {
    if (isValidMove(row, col, num)) {
      board.value[row][col].value = num
      if (generateSolution(row, col + 1)) {
        return true
      }
      board.value[row][col].value = 0
    }
  }
  return false
}

// 检查移动是否有效
const isValidMove = (row, col, num) => {
  // 检查行
  for (let i = 0; i < BOARD_SIZE; i++) {
    if (board.value[row][i].value === num) return false
  }

  // 检查列
  for (let i = 0; i < BOARD_SIZE; i++) {
    if (board.value[i][col].value === num) return false
  }

  // 检查3x3宫格
  const boxRow = Math.floor(row / 3) * 3
  const boxCol = Math.floor(col / 3) * 3
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      if (board.value[boxRow + i][boxCol + j].value === num) return false
    }
  }

  return true
}

// 工具函数
const shuffle = (array) => {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]]
  }
  return array
}

const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

// 游戏操作
const selectCell = (row, col) => {
  if (!isPlaying.value || isPaused.value || board.value[row][col].fixed) return
  selectedCell.value = { row, col }
}

const fillNumber = (num) => {
  if (!isPlaying.value || isPaused.value) return
  const { row, col } = selectedCell.value
  if (row === -1 || col === -1 || board.value[row][col].fixed) return

  if (!isValidMove(row, col, num)) {
    errors.value++
    if (errors.value >= MAX_ERRORS) {
      endGame(false)
    }
    return
  }

  board.value[row][col].value = num
  checkWin()
}

const clearCell = () => {
  if (!isPlaying.value || isPaused.value) return
  const { row, col } = selectedCell.value
  if (row === -1 || col === -1 || board.value[row][col].fixed) return
  board.value[row][col].value = 0
}

const checkWin = () => {
  // 检查是否所有格子都已填满且正确
  for (let i = 0; i < BOARD_SIZE; i++) {
    for (let j = 0; j < BOARD_SIZE; j++) {
      if (board.value[i][j].value === 0) return
    }
  }
  endGame(true)
}

// 游戏控制
const startNewGame = () => {
  initBoard()
  generatePuzzle()
  selectedCell.value = { row: -1, col: -1 }
  errors.value = 0
  gameTime.value = 0
  gameOver.value = false
  isPaused.value = false
  isPlaying.value = true
  
  if (gameTimer) clearInterval(gameTimer)
  gameTimer = setInterval(() => {
    if (!isPaused.value) {
      gameTime.value++
    }
  }, 1000)
}

const togglePause = () => {
  isPaused.value = !isPaused.value
}

const endGame = (win) => {
  isPlaying.value = false
  gameOver.value = true
  isWin.value = win
  clearInterval(gameTimer)
}

const checkSolution = () => {
  // 检查当前填写是否正确
  for (let i = 0; i < BOARD_SIZE; i++) {
    for (let j = 0; j < BOARD_SIZE; j++) {
      if (board.value[i][j].value !== 0 && !isValidMove(i, j, board.value[i][j].value)) {
        errors.value++
        if (errors.value >= MAX_ERRORS) {
          endGame(false)
        }
        return
      }
    }
  }
}

// 辅助函数
const isHighlighted = (row, col) => {
  if (selectedCell.value.row === -1) return false
  return row === selectedCell.value.row || 
         col === selectedCell.value.col ||
         (Math.floor(row / 3) === Math.floor(selectedCell.value.row / 3) &&
          Math.floor(col / 3) === Math.floor(selectedCell.value.col / 3))
}

const hasError = (row, col) => {
  const value = board.value[row][col].value
  if (value === 0) return false

  // 临时清除当前值以检查是否有冲突
  board.value[row][col].value = 0
  const isValid = isValidMove(row, col, value)
  board.value[row][col].value = value
  return !isValid
}

const canUseNumber = (num) => {
  return selectedCell.value.row !== -1 && 
         !board.value[selectedCell.value.row][selectedCell.value.col].fixed
}

// 生命周期钩子
onMounted(() => {
  startNewGame()
})

onUnmounted(() => {
  if (gameTimer) clearInterval(gameTimer)
})
</script>

<style scoped>
.sudoku-container {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: var(--theme-bg, #1a1a1a);
  padding: 20px;
}

.game-wrapper {
  display: grid;
  grid-template-columns: auto 280px;
  gap: 20px;
  max-width: 1000px;
  width: 100%;
}

/* 游戏主区域 */
.game-board {
  display: grid;
  grid-template-rows: repeat(9, 1fr);
  width: 500px;
  height: 500px;
  background-color: var(--theme-container-bg, #1f2937);
  padding: 2px;
  border-radius: 8px;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.board-row {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  gap: 1px;
}

.board-cell {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: var(--theme-bg, #374151);
  font-size: 24px;
  font-weight: bold;
  color: var(--theme-text-color, #e2e8f0);
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid var(--theme-border-color, #4b5563);
}

/* 添加选中和高亮样式 */
.board-cell.selected {
  background-color: var(--theme-primary-color, #3b82f6);
  color: white;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2);
}

.board-cell.highlighted {
  background-color: var(--theme-secondary-bg, #4b5563);
}

.board-cell.fixed {
  color: var(--theme-primary-color, #3b82f6);
  cursor: not-allowed;
  font-weight: 900;
}

.board-cell.error {
  color: #ef4444;
  animation: shake 0.3s;
}

/* 添加错误动画 */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-2px); }
  75% { transform: translateX(2px); }
}

.board-cell:nth-child(3n) {
  border-right: 2px solid var(--theme-border-color, #4b5563);
}

.board-row:nth-child(3n) .board-cell {
  border-bottom: 2px solid var(--theme-border-color, #4b5563);
}

/* 右侧控制面板 */
.control-panel {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 数字选择面板 */
.number-pad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  padding: 16px;
  background-color: var(--theme-container-bg, #1f2937);
  border-radius: 8px;
}

.number-button {
  padding: 12px;
  font-size: 18px;
  font-weight: bold;
  color: white;
  background-color: var(--theme-secondary-bg, #4b5563);
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
}

/* 添加按钮悬停效果 */
.number-button:hover:not(:disabled) {
  background-color: var(--theme-primary-color, #3b82f6);
  transform: translateY(-1px);
}

.number-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.number-button.clear {
  grid-column: span 3;
  background-color: #ef4444;
}

.number-button.clear:hover:not(:disabled) {
  background-color: #dc2626;
}

/* 游戏状态面板 */
.game-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  padding: 16px;
  background-color: var(--theme-container-bg, #1f2937);
  border-radius: 8px;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.stat-label {
  font-size: 12px;
  color: var(--theme-text-color, #e2e8f0);
  opacity: 0.8;
}

.stat-value {
  font-size: 18px;
  font-weight: bold;
  color: var(--theme-primary-color, #3b82f6);
}

/* 添加错误状态样式 */
.stat-value.danger {
  color: #ef4444;
  animation: pulse 1s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

/* 控制按钮组 */
.button-group {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.control-button {
  padding: 10px;
  font-size: 14px;
  color: white;
  background-color: var(--theme-secondary-bg, #4b5563);
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
}

.control-button.primary {
  grid-column: span 2;
  background-color: var(--theme-primary-color, #3b82f6);
}

/* 难度选择 */
.difficulty-select {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  background-color: var(--theme-container-bg, #1f2937);
  border-radius: 6px;
}

.difficulty-select select {
  flex: 1;
  padding: 6px;
  background-color: var(--theme-secondary-bg, #4b5563);
  color: white;
  border: none;
  border-radius: 4px;
}

/* 游戏说明 */
.game-instructions {
  padding: 16px;
  background-color: var(--theme-container-bg, #1f2937);
  border-radius: 8px;
}

.game-instructions h3 {
  margin: 0 0 8px;
  font-size: 16px;
  color: var(--theme-primary-color, #3b82f6);
}

.game-instructions ul {
  margin: 0;
  padding-left: 16px;
  font-size: 13px;
  line-height: 1.5;
}

/* 响应式设计 */
@media (max-width: 900px) {
  .game-wrapper {
    grid-template-columns: 1fr;
    justify-items: center;
  }

  .game-board {
    width: 100%;
    max-width: 500px;
    height: auto;
    aspect-ratio: 1;
  }

  .control-panel {
    width: 100%;
    max-width: 500px;
  }

  .game-stats {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 500px) {
  .game-board {
    width: 100%;
    font-size: 16px;
  }

  .number-button {
    padding: 8px;
    font-size: 16px;
  }

  .stat-value {
    font-size: 16px;
  }
}

.game-over {
  position: fixed;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(4px);
}

.game-over-content {
  background-color: var(--theme-container-bg, #1f2937);
  padding: 30px;
  border-radius: 12px;
  text-align: center;
  color: white;
}

.result-stats {
  margin: 20px 0;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  margin-bottom: 8px;
}

.restart-button {
  padding: 12px 24px;
  font-size: 16px;
  color: white;
  background-color: var(--theme-primary-color, #3b82f6);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
}

.restart-button:hover {
  filter: brightness(1.1);
}
</style> 